package org.tokaf.bestcolumnfinder;

import org.tokaf.TopKElement;
import org.tokaf.algorithm.Algorithm;
import org.tokaf.datasearcher.DataSearcher;
import org.tokaf.rater.Rater;

/**
 * <p>The weight of column is proportional to derivation in data. Derivation is
 * computed as the difference of rating of actual element and the rating of
 * (i-h)-th element, where i is actual position in the list.</p> <p>Copyright
 * (c) 2006</p>
 * @author Alan Eckhardt
 * @version 1.0
 */
public class DerivationInDataFinder extends DerivationInPointFinder {
	public DerivationInDataFinder(DataSearcher[] data, Rater rater) {
		super(data, rater);
	}

	int h = 100;

	protected boolean computeDerivationsInThreshold(Algorithm alg) {
		boolean end = true;
		Rater rater = alg.getRater();
		DataSearcher[] data = alg.getDataSearchers();
		TopKElement threshold = alg.getThreshold();
		// if (nextValue(data) == -1)
		for (int i = 0; i < myData.length; i++) {
			if (!myData[i].hasNext())
				continue;

			if (threshold == null) {
				throw new NullPointerException();
			}
			Object value = data[i].getFieldAtPosition(data[i].getPosistion()
					- h, 2);
			derivations[i] = rater.getDerivation(i, data, threshold);
			if (!threshold.isNull(i) && value != null)
				// We multiply by x(i)-x(i+1)
				derivations[i] *= -threshold.getRating(i)
						+ data[i].getNormalizer().Normalize(value);
			if (derivations[i] != 0)
				end = false;
		}
		return end;
	}

	protected boolean computeDerivationsInData(Algorithm alg) {
		boolean end = true;
		Rater rater = alg.getRater();
		DataSearcher[] data = alg.getDataSearchers();
		// if (nextValue(data) == -1)
		for (int i = 0; i < myData.length; i++) {
			if (!myData[i].hasNext())
				continue;

			TopKElement el = alg.findEntity(last[i]);
			if (el == null) {
				throw new NullPointerException();
			}
			Object value = data[i].getFieldAtPosition(data[i].getPosistion()
					- h, 2);

			derivations[i] = rater.getDerivation(i, data, el);
			if (!el.isNull(i) && value != null)
				// We multiply by x(i)-x(i+1)
				derivations[i] *= -el.getRating(i)
						+ data[i].getNormalizer().Normalize(value);
			if (derivations[i] != 0)
				end = false;
		}
		return end;
	}

}
